#include "messageeditarea.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include "historymessagewidget.h"

using namespace model;


/**********************************************************************************************
 * 右边窗口中的 消息编辑区域
 **********************************************************************************************/
MessageEditArea::MessageEditArea(QWidget *parent)
    :QWidget(parent)
{
    //1.设置必要的属性
    this->setFixedHeight(200);
    this->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed);

    //2.创建垂直布局管理器
    QVBoxLayout* vlayout = new QVBoxLayout();
    vlayout->setSpacing(0);
    vlayout->setContentsMargins(0,0,10,10);
    this->setLayout(vlayout);

    //3.创建水平布局管理器
    QHBoxLayout* hlayout = new QHBoxLayout();
    hlayout->setSpacing(10);
    hlayout->setContentsMargins(2,0,0,0);
    hlayout->setAlignment(Qt::AlignLeft | Qt::AlignTop);
    vlayout->addLayout(hlayout);


    //4.设置四个按钮，添加到水平布局管理器中
    QString btnStyle = "QPushButton { background-color: transparent; border: none; } QPushButton:pressed { background-color: rgb(230, 230, 230); }";
    QSize btnSize(25,25);
    QSize iconSize(25,25);
    sendImageBtn = new QPushButton();
    sendImageBtn->setFixedSize(btnSize);
    sendImageBtn->setIconSize(iconSize);
    sendImageBtn->setIcon(QIcon(":/resource/sendImage.png"));
    sendImageBtn->setStyleSheet(btnStyle);
    hlayout->addWidget(sendImageBtn,0,Qt::AlignTop | Qt::AlignLeft);

    sendFileBtn = new QPushButton();
    sendFileBtn->setFixedSize(btnSize);
    sendFileBtn->setIconSize(iconSize);
    sendFileBtn->setIcon(QIcon(":/resource/sendFile.png"));
    sendFileBtn->setStyleSheet(btnStyle);
    hlayout->addWidget(sendFileBtn,0,Qt::AlignTop | Qt::AlignLeft);

    sendSpeechBtn = new QPushButton();
    sendSpeechBtn->setFixedSize(btnSize);
    sendSpeechBtn->setIconSize(iconSize);
    sendSpeechBtn->setIcon(QIcon(":/resource/sendSpeech.png"));
    sendSpeechBtn->setStyleSheet(btnStyle);
    hlayout->addWidget(sendSpeechBtn,0,Qt::AlignTop | Qt::AlignLeft);

    showHistoryBtn = new QPushButton();
    showHistoryBtn->setFixedSize(btnSize);
    showHistoryBtn->setIconSize(iconSize);
    showHistoryBtn->setIcon(QIcon(":/resource/historyMessage.png"));
    showHistoryBtn->setStyleSheet(btnStyle);
    hlayout->addWidget(showHistoryBtn,0,Qt::AlignTop | Qt::AlignLeft);

    //5. 添加文本编辑框
    textEdit = new QPlainTextEdit();
    textEdit->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
    textEdit->setStyleSheet("QPlainTextEdit { border: none; background-color: transparent; font-size: 14px; }");
    textEdit->verticalScrollBar()->setStyleSheet("QScrollBar:vertical { width: 2px; background-color: rgb(45, 45, 45); }");
    vlayout->addWidget(textEdit);

    //6.添加提示录制中
    tipLabel = new QLabel();
    tipLabel->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
    tipLabel->setText("录音中...");
    tipLabel->setAlignment(Qt::AlignCenter);
    tipLabel->setFont(QFont("微软雅黑",24,600));
    vlayout->addWidget(tipLabel);
    tipLabel->hide();

    //7.发送按钮
    sendTextBtn = new QPushButton();
    sendTextBtn->setText("发送");
    sendTextBtn->setFixedSize(100, 40);
    QString style = "QPushButton { font-size: 16px; color: rgb(7, 193, 96); border: none; background-color: rgb(233, 233, 233); border-radius: 10px; } ";
    style += "QPushButton:hover { background-color: rgb(210, 210, 210); }";
    style += "QPushButton:pressed { background-color: rgb(190, 190, 190); }";
    sendTextBtn->setStyleSheet(style);
    vlayout->addWidget(sendTextBtn, 0, Qt::AlignRight | Qt::AlignVCenter);

    //8.关联信号槽
    initSingalSlots();
}

void MessageEditArea::initSingalSlots()
{
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    //1. 关联显示历史消息信号槽
    connect(showHistoryBtn, &QPushButton::clicked, this, [=]() {
        if(dataCenter->getCurrentChatSessionId().isEmpty())
        {
            return;
        }
        HistoryMessageWidget* historyMessageWidget = new HistoryMessageWidget(this);
        historyMessageWidget->exec();
    });

    //2.关联发送信息信号槽
    connect(sendTextBtn,&QPushButton::clicked,this,&MessageEditArea::sendMessageTextMessage);
    connect(dataCenter,&DataCenter::sendMessageDone, this, &MessageEditArea::addSelfMessage);

    //3.关联收到消息信号槽
    connect(dataCenter,&DataCenter::receiveMessageDone,this, &MessageEditArea::addOtherMessage);

    //4.关联发送图片按钮的信号槽
    connect(sendImageBtn,&QPushButton::clicked,this,&MessageEditArea::clickSendImageMessage);

    //5.关联发送文件按钮的信号槽
    connect(sendFileBtn,&QPushButton::clicked,this,&MessageEditArea::clickSendFileMessage);

    //6.发送语音消息
    connect(sendSpeechBtn,&QPushButton::pressed,this,&MessageEditArea::pressSendSpeechMessage);
    connect(sendSpeechBtn,&QPushButton::released,this,&MessageEditArea::releaseSendSpeechMessage);
    //7.关联录音结束的信号槽，然后发送
    SoundRecorder* soundRecorder = SoundRecorder::getInstance();
    connect(soundRecorder,&SoundRecorder::soundRecordDone,this,&MessageEditArea::sendSpeechMessage);
}

void MessageEditArea::sendMessageTextMessage()
{
    //1.确认当前是否有会话被选中
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    if(dataCenter->getCurrentSessionId().isEmpty())
    {
        LOG() << "当前未选中会话，不发送任何消息";
        Toast::showMessage("当前未选中会话，不发送任何消息");
        return;
    }

    //2.获取到输入框中的内容
    const QString& content = textEdit->toPlainText().trimmed();
    if(content.isEmpty())
    {
        LOG() << "输入框为空";
        return;
    }
    //3.清空输入框已有内容
    textEdit->clear();

    //4.通过网络发送
    dataCenter->sendTextMessageAsync(dataCenter->getCurrentSessionId(),content);
}

void MessageEditArea::addSelfMessage(model::MessageType messageType, const QByteArray &content, const QString &extraInfo)
{
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    const QString& currentChatSessionId = dataCenter->getCurrentSessionId();

    //1.构造出一个消息对象
    model::MessageInfo messageInfo = MessageInfo::makeMessage(messageType,
                                                              currentChatSessionId,
                                                              *dataCenter->getMyself(),
                                                              content,
                                                              extraInfo);
    dataCenter->addMessage(messageInfo);
    // 2. 把这个新的消息, 显示到消息展示区
    MainWidget* mainWidget = MainWidget::getInstance();
    MessageShowArea* messageShowArea = mainWidget->getMessageShowArea();
    messageShowArea->addBackMessage(false, messageInfo);

    // 3. 控制消息显示区, 滚动条, 滚动到末尾.
    messageShowArea->scrollToEnd();


    // 4. 发送信号, 通知会话列表, 更新最后一条消息
    emit dataCenter->updateLastMessage(currentChatSessionId);
}

void MessageEditArea::addOtherMessage(const model::MessageInfo &message)
{
    //1.拿到消息展示区
    MainWidget* mainWidget = MainWidget::getInstance();
    MessageShowArea* messageShowArea = mainWidget->getMessageShowArea();
    //2. 把这个新的消息, 显示到消息展示区
    messageShowArea->addBackMessage(true,message);
    messageShowArea->scrollToEnd();
    // Toast::showMessage("收到一条新的消息");
}

void MessageEditArea::clickSendImageMessage()
{
    LOG() << "触发点击消息按钮";
    DataCenter* dataCenter = DataCenter::getInstance();
    if(dataCenter->getCurrentChatSessionId().isEmpty())
    {
        LOG() << "为选中会话，不能发送消息";
        return;
    }

    //弹出选择消息的对话框
    QString filter = "Image files (*.png *.jpeg *.jpg *.bmp)";
    QString imagePath = QFileDialog::getOpenFileName(this, "选择图⽚",QDir::homePath(), filter);
    if (imagePath.isEmpty()) {
        LOG() << "取消图⽚选择";
        return;
    }

    //读取图片内容
    QByteArray imageContent = loadFile2ByteArray(imagePath);
    //通过网络发送消息
    dataCenter->sendImageMessageAsync(dataCenter->getCurrentChatSessionId(),imageContent);
    //此处请求回处理，由addSelfMessage处理
}

void MessageEditArea::clickSendFileMessage()
{
    //1.判断当前是否选择了会话
    DataCenter* dataCenter = DataCenter::getInstance();
    if(dataCenter->getCurrentChatSessionId().isEmpty())
    {
        return;
    }

    //2.弹出对话框，选择文件
    QString filter = "";
    QString filePath = QFileDialog::getOpenFileName(this,"选择文件",QDir::homePath(),filter);   //默认打开window用户目录
    if(filePath.isEmpty())
    {
        LOG() << "用户取消了发送文件";
        return;
    }

    //3.读取文件内容
    QByteArray fileContent = loadFile2ByteArray(filePath);
    //4.获取文件名
    QFileInfo fileInfo(filePath);
    const QString fileName = fileInfo.fileName();
    //5.发送请求
    dataCenter->sendFileMessageAsync(dataCenter->getCurrentChatSessionId(),fileName,fileContent);
}

void MessageEditArea::pressSendSpeechMessage()
{
    //判断是否选中会话
    DataCenter* dataCenter = DataCenter::getInstance();
    if(dataCenter->getCurrentChatSessionId().isEmpty())
    {
        LOG() << "未选中会话，无法发送语音消息";
        return;
    }

    //切换语音按钮的图标
    sendSpeechBtn->setIcon(QIcon(":/resource/speech_active.png"));

    //开始录音
    SoundRecorder* soundRecorder = SoundRecorder::getInstance();
    soundRecorder->startRecord();

    //展现开始录音
    tipLabel->show();
    textEdit->hide();
}

void MessageEditArea::releaseSendSpeechMessage()
{
    //判断是否选中会话
    DataCenter* dataCenter = DataCenter::getInstance();
    if(dataCenter->getCurrentChatSessionId().isEmpty())
    {
        LOG() << "未选中会话，无法发送语音消息";
        return;
    }

    //切换语音按钮的图标
    sendSpeechBtn->setIcon(QIcon(":/resource/sendSpeech.png"));

    //开始录音
    SoundRecorder* soundRecorder = SoundRecorder::getInstance();
    soundRecorder->stopRecord();

    tipLabel->hide();
    textEdit->show();
}

void MessageEditArea::sendSpeechMessage(const QString &path)
{

    DataCenter* dataCenter = DataCenter::getInstance();
    //1.读取到语音文件的内容
    QByteArray content = loadFile2ByteArray(path);
    if(content.isEmpty())
    {
        LOG() << "语音文件加载失败";
        return;
    }
    //2.网络发送语音消息
    dataCenter->sendSpeechMessageAsync(dataCenter->getCurrentChatSessionId(),content);
}

